import { defineComponent, PropType, reactive, ref, VNode } from 'vue';
import { useNamespace } from '@ibiz-template/vue3-util';
import { isNumber } from 'lodash-es';
import {
  IModalData,
  IModalOptions,
  IOverlayContainer,
  Modal,
  ViewMode,
} from '@ibiz-template/runtime';
import './modal.scss';
import { OverlayContainer } from '../overlay-container/overlay-container';
import { useUIStore } from '../store';

export const AppModalComponent = defineComponent({
  props: {
    opts: {
      type: Object as PropType<IModalOptions>,
      default: () => ({}),
    },
  },
  setup(props, ctx) {
    const ns = useNamespace('modal');
    const isShow = ref(false);
    let data: IData;

    const { zIndex } = useUIStore();
    const modalZIndex = zIndex.increment();

    // 处理自定义样式,添加z-index变量
    const customStyle = reactive<IData>({
      [ns.cssVarBlockName('z-index')]: modalZIndex,
    });
    const { width, height } = props.opts;
    if (width) {
      customStyle.width = isNumber(width) ? `${width}px` : width;
    }
    if (height) {
      customStyle.height = isNumber(height) ? `${height}px` : height;
    }

    // 合并options
    const options = ref<IModalOptions>({ footerHide: true, modalClass: '' });
    if (props.opts) {
      Object.assign(options.value, props.opts);
    }

    const modal = new Modal({
      mode: ViewMode.MODAL,
      viewUsage: 2,
      dismiss: (_data: IData) => {
        zIndex.decrement();
        isShow.value = false;
        data = _data;
      },
    });

    // Modal自身的所有关闭方式最终都走这个
    const onBeforeClose = async (done: () => void) => {
      const isClose = await modal.dismiss();
      if (isClose) {
        done();
      }
    };

    // 外部函数式调用
    const dismiss = (_data?: IModalData) => {
      modal.dismiss(_data);
    };

    const present = () => {
      isShow.value = true;
    };
    // 完全关闭后调用销毁
    const onClosed = () => {
      ctx.emit('dismiss', data);
    };

    return {
      ns,
      isShow,
      options,
      modalZIndex,
      customStyle,
      modal,
      present,
      dismiss,
      onClosed,
      onBeforeClose,
    };
  },
  render() {
    return (
      <el-dialog
        model-value={this.isShow}
        align-center={true}
        class={[
          this.ns.b(),
          this.options.placement && this.ns.m(this.options.placement),
          this.options.modalClass,
        ]}
        style={this.customStyle}
        onClosed={this.onClosed}
        before-close={this.onBeforeClose}
      >
        {this.$slots.default?.(this.modal)}
      </el-dialog>
    );
  },
});

/**
 * 创建模态框
 *
 * @author chitanda
 * @date 2022-12-29 15:12:50
 * @export
 * @param {() => VNode} render
 * @param {(IModalOptions | undefined)} [opts]
 * @return {*}  {IOverlayContainer}
 */
export function createModal(
  render: () => VNode,
  opts?: IModalOptions | undefined,
): IOverlayContainer {
  return new OverlayContainer(AppModalComponent, render, opts);
}
